#include "metaclass.h"
#include "system/istream.h"

namespace gecko
{

	//---------------------------------------------------------------------------------------------

	MetaClass::MetaClass( char *  className, Member * memberArray, int size, MetaClass& parentClass )
		: m_version(0)
	{
		sprintf(m_className, "%s", className);

		for (MemberMap::iterator itr = parentClass.m_memberMap.begin(); itr != parentClass.m_memberMap.end(); ++itr)
		{
			m_memberMap.push_back((*itr));
		}

		for (int i = 0; i < size; i++)
		{
			// concatenate class name onto member name
			char memberName[MAX_NAME_LEN];
			sprintf(memberName, "%s::%s", className, memberArray[i].name);
			sprintf(memberArray[i].name, "%s", memberName);
			m_memberMap.push_back(memberArray[i]);
		}

		GenerateCheckSum();
	}

	//---------------------------------------------------------------------------------------------

	MetaClass::MetaClass( char *  className )
		: m_version(0)
	{
		sprintf(m_className, "%s", className);
		GenerateCheckSum();
	}

	//---------------------------------------------------------------------------------------------

	MetaClass::MetaClass()
	{

	}

	//---------------------------------------------------------------------------------------------

	void MetaClass::GenerateCheckSum()
	{
		int hash = 0;

		// do some crappy checksum hash type shit for now...
		for (MemberMap::iterator itr = m_memberMap.begin(); itr != m_memberMap.end(); ++itr)
		{
			for (unsigned int i = 0; i < strlen((*itr).name); i++)
			{
				hash += int((*itr).name[i] | 0x123456780);
				hash += (*itr).size;
			}
		}

		m_version = hash;
	}

	//---------------------------------------------------------------------------------------------

	void MetaClass::SerialiseMetaData( IStream& stream )
	{
		stream.SerialiseString(m_className);

		unsigned int memberCount = (unsigned int)m_memberMap.size();
		stream.Serialise(memberCount);

		switch (stream.GetMode())
		{
		case IStream::ModeRead:
			{
				for (unsigned int i = 0; i < memberCount; i++)
				{
					Member member;
					stream.SerialiseString(member.name);
					stream.Serialise(member.type);
					stream.Serialise(member.size);
					m_memberMap.push_back(member);
				}
			}
			break;

		case IStream::ModeWrite:
			{
				for (MemberMap::iterator itr = m_memberMap.begin(); itr != m_memberMap.end(); ++itr)
				{
					stream.SerialiseString((*itr).name);
					stream.Serialise((*itr).type);
					stream.Serialise((*itr).size);
				}
			}
			break;
		}
	}

	//---------------------------------------------------------------------------------------------

	bool MetaClass::operator==( const MetaClass & rhs )
	{
		return m_version == rhs.m_version;
	}

	//---------------------------------------------------------------------------------------------

	bool MetaClass::operator!=( const MetaClass & rhs )
	{
		return m_version != rhs.m_version;
	}

	//---------------------------------------------------------------------------------------------

	const MetaClass::MemberMap & MetaClass::GetMemberMap() const
	{
		return m_memberMap;
	}

	//---------------------------------------------------------------------------------------------

	char * MetaClass::GetName()
	{
		return m_className;
	}

}
